package com.xf.lastmall.service;


import com.xf.lastmall.feign.PayServiceApi;
import com.xf.lastmall.moudle.exception.OrderException;
import com.xf.lastmall.moudle.request.PayRequestParam;
import com.xf.lastmall.order.api.common.Response;
import com.xf.lastmall.order.api.constant.OrderType;
import com.xf.lastmall.order.api.constant.PayWay;
import com.xf.lastmall.moudle.entity.OrderMainEntity;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Map;

/**
 * Created by wangzhaoqian5 on 2018/7/23.
 */
@Component
public class OrderRefTool {
    private static final Logger logger = LoggerFactory.getLogger(OrderRefTool.class);
    /**
     * 标识新订单   回调时会分开回调
     */
    private static final String ORDER_NEW = "order.new";

    private static final String PLATEFORM_WXA = "wxa";

    private static final int ORDER_INVALID_TIME = 15;

    private static final String IPP_ENABLE_CONFIG_KEY = "system:config:support.ipp.enable";
    private static final String IPP_MALL_CONFIG_KEY = "system:config:support.ipp.malls";
    private static final String DEFAULT_MERCHANT_NO = "000000000000005";
    @Resource
    private PayServiceApi payServiceApi;

    @Resource
    private OrderMainService orderMainService;


    /**
     * 调用支付接口
     */
    public Response toPay(OrderMainEntity entity, int payType, String openId) {

        //一点万象支付
        PayRequestParam payRequestParam = new PayRequestParam();
        payRequestParam.setOrderNo(entity.getOrderNo());
        payRequestParam.setPayWay(PayWay.fromValue(payType));

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(entity.getCreateTime());
        calendar.add(Calendar.MINUTE, ORDER_INVALID_TIME);

        payRequestParam.setInvalidTime(calendar.getTime());
        payRequestParam.setRequestBiz(ORDER_NEW);
        payRequestParam.setMallCode(entity.getMallCode());
        payRequestParam.setWxaAppId(entity.getWxaAppId());


        //是跨场售卖，外部商户编码默认来源场编码值；
        //如果 渠道是空或者是默认渠道，需要赋值为 外部商户自己的商户编码
        if (OrderType.OUT_MERCHANT.getValue().equals(entity.getOrderType())) {
            payRequestParam.setMerchantCode(entity.getServiceMerchantCode());
        } else {
            payRequestParam.setMerchantCode(entity.getMallCode());
        }

        payRequestParam.setMobile(entity.getMemberMobile());
        payRequestParam.setChannel(entity.getSource());
        payRequestParam.setUserId(entity.getMemberId());
        payRequestParam.setPayAmount(entity.getTotalPrice());
        payRequestParam.setRequestFrom(entity.getSource());
        payRequestParam.setOpenId(openId);
        payRequestParam.setTxnTime(entity.getCreateTime());
        //处理在微信小程序下的单在APP不能支付的问题
        Response<?> payRes = dealDifferentToPay(payRequestParam);
        if (!payRes.isSuccess()) {
            return payRes;
        }
        try {
            Map<String, Object> param = payServiceApi.buildPayRequestMap(payRequestParam);
            if (param.containsKey("payErrMsg")) {
                throw new OrderException((String) param.get("payErrMsg"));
            }
            param.put("orderInvalidTime", ORDER_INVALID_TIME);
            return new Response<>(param);
        } catch (Exception e) {
            logger.error("一点万象支付异常 orderNo:{} e:{}", entity.getOrderNo(), e.getMessage(), e);
            return new Response<>(Response.Status.FAILED, e.getCause() != null ? e.getCause().getMessage() : e.getMessage());
        }

    }

    /**
     * 处理在微信小程序下的单在APP不能支付的问题
     * //支付方式相同，但是平台不同，则重新生成orderNo，否则会支付失败，报用户订单号重复
     *
     * @param newPayRequestParam
     */
    private Response dealDifferentToPay(PayRequestParam newPayRequestParam) {
        Response payRes = new Response();

/*        Response payRes = new Response();
        if (newPayRequestParam.getPayWay() == null
                || newPayRequestParam.getRequestFrom() == null
                || newPayRequestParam.getOrderNo() == null) {
            return payRes;
        }

        String newParamValueStr = newPayRequestParam.toString();
        String key = "mixc:new:order:toPay:" + newPayRequestParam.getOrderNo();

        //取历史支付记录参数
        String oldParamStr = stringRedisTemplate.opsForValue().get(key);

        if (!StringUtils.hasText(oldParamStr)) {
            stringRedisTemplate.opsForValue().set(key, newParamValueStr, ORDER_INVALID_TIME, TimeUnit.MINUTES);
            return payRes;
        }

        PayRequestParam oldPayRequestParam = JSON.parseObject(oldParamStr, PayRequestParam.class);
        String oldRequestFrom = oldPayRequestParam.getRequestFrom();
        String oldRequestFromText = RequestFrom.fromValue(oldRequestFrom).getText();
        if (NewPlatformEnum.ANDROID.getText().equalsIgnoreCase(oldRequestFrom) ||
                NewPlatformEnum.IOS.getText().equalsIgnoreCase(oldRequestFrom)) {
            oldRequestFrom = "APP";
            oldRequestFromText = "APP";
        }
        String newRequestFrom = newPayRequestParam.getRequestFrom();
        if (NewPlatformEnum.ANDROID.getText().equalsIgnoreCase(newRequestFrom) ||
                NewPlatformEnum.IOS.getText().equalsIgnoreCase(newRequestFrom)) {
            newRequestFrom = "APP";
        }
        if (newPayRequestParam.getPayWay().equals(oldPayRequestParam.getPayWay()) && !newRequestFrom.equals(oldRequestFrom)) {
            //支付方式相同，但是平台不同，则重新生成orderNo，否则会支付失败，报用户订单号重复
            return new Response(Response.Status.FAILED, String.format("请返回原下单渠道【%s】进行支付", oldRequestFromText));
        }*/
        return payRes;
    }

    public boolean verifyResult(String payChannel, String orderNo, String payType, String payData) {
        boolean flag = false;


        Response response = payServiceApi.verifyResult(payType, orderNo, payData);
        if (response.isSuccess()) {
            flag = true;
        }
        return flag;
    }

    /**
     * 是否支持综合支付
     * 目前支持所有平台   不区分appVersion
     *
     * @param mallCode
     * @return
     */
    public boolean isSupportIpp(String mallCode) {
        //综合支付开关
//        String supportIppEnable = stringRedisTemplate.opsForValue().get(IPP_ENABLE_CONFIG_KEY);
//        if (StringUtil.isNoneBlank(supportIppEnable) && "true".equalsIgnoreCase(supportIppEnable)) {
//            return isSupportMall(mallCode);
//        }
        return false;
    }

}
